package com.mc.lp.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.transaction.Transactional;

import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.mc.lp.database.cache.CacheServiceType;
import com.mc.lp.database.cache.SocialBehaviourCache;
import com.mc.lp.database.dao.ISocialBehaviourRecordDAO;
import com.mc.lp.database.entity.SocialBehaviorRecordEntity;
import com.mc.lp.database.entity.helper.SocialBehaviorRecordHelper;
import com.mc.lp.database.entity.type.StrengthWeaknessType;
import com.mc.lp.database.exception.ConcurrentAccessException;
import com.mc.lp.database.service.handler.util.GenericAggregator;
import com.mc.lp.service.MicroCampusAbstractService;
import com.mc.lp.service.SocialBehaviorService;
import com.mc.lp.shared.util.constants.ResponseStatus;
import com.mc.lp.shared.vo.EntitySaveResponse;
import com.mc.lp.shared.vo.IValueObject;
import com.mc.lp.shared.vo.SearchCriteriaVO;
import com.mc.lp.shared.vo.ServiceResponse;
import com.mc.lp.shared.vo.SocialBehaviorRecordVO;
import com.mc.lp.shared.vo.StudentRecordVO;
import com.mc.lp.shared.vo.user.bubble.BubbleRow;
import com.mc.lp.shared.vo.user.bubble.BubbleValue;

/*
 * @author aphanda
 * @date Sep 21, 2014
 * @time 12:50:44 AM
 */


@Service
public class SocialBehaviorServiceImpl extends
MicroCampusAbstractService<SocialBehaviorServiceImpl> implements SocialBehaviorService{
	
	
	@Resource
	ISocialBehaviourRecordDAO socialBehaviourRecordDAO;
	
	SocialBehaviorRecordHelper helper = new SocialBehaviorRecordHelper();

	@Transactional
	public IValueObject saveSocialBehaviours(StudentRecordVO studentRecordVO)
			throws DataAccessException, ConcurrentAccessException {

		
		
		ArrayList<EntitySaveResponse> saveResponse = new ArrayList<EntitySaveResponse>();
		ServiceResponse<EntitySaveResponse> serviceResponse = new ServiceResponse<EntitySaveResponse>();
		SocialBehaviorRecordHelper helper = new SocialBehaviorRecordHelper();
			for (SocialBehaviorRecordVO vo : studentRecordVO.getSocialBehaviourActivities()) {
				EntitySaveResponse response = new EntitySaveResponse(vo.getSid(), "SocialBehaviour");
				
				SocialBehaviorRecordEntity dbRecord = new SocialBehaviorRecordEntity();
				SocialBehaviorRecordEntity socialBehavEntity = helper.getEntity(vo);
				socialBehavEntity.setStudentEntity(studentRecordVO.getSearchCriteria().getStudentEntityId());

				if (!vo.isNewRow()) {
					if (vo.getSid() != 0) {
						dbRecord = socialBehaviourRecordDAO.findById(vo.getSid());
						// Delete the entity which is marked as deleted on UI
						if (vo.isRowDeleted()) {
								try {
									socialBehaviourRecordDAO.delete(dbRecord);
									response.setStatus(ResponseStatus.SUCCESS);
									serviceResponse.setStatus(ResponseStatus.SUCCESS);
								} catch (DataAccessException e) {
									getLogger().error("saveSocialBehaviours()", e);
									response.setStatus(ResponseStatus.FAILED);
									response.setMsg(e.getMessage());
									
									serviceResponse.setStatus(ResponseStatus.FAILED);
									serviceResponse.setMsg(e.getMessage());
									
								} catch (ConcurrentAccessException e) {
									getLogger().error("saveSocialBehaviours()", e);
									response.setStatus(ResponseStatus.FAILED);
									response.setMsg(e.getMessage());
									serviceResponse.setStatus(ResponseStatus.FAILED);
									serviceResponse.setMsg(e.getMessage());
								}
							continue;
						}
						//AP this we need to do with reflection to avoid any kind or missed property situation.
						//if (!dbRecord.equals(vo)) {
							try {
								helper.setEntity(vo, dbRecord);
								socialBehaviourRecordDAO.saveOrUpdate(dbRecord);
								response.setStatus(ResponseStatus.SUCCESS);
								serviceResponse.setStatus(ResponseStatus.SUCCESS);
							} catch (DataAccessException e) {
								getLogger().error("saveSocialBehaviours()", e);
								response.setStatus(ResponseStatus.FAILED);
								response.setMsg(e.getMessage());
								serviceResponse.setStatus(ResponseStatus.FAILED);
								serviceResponse.setMsg(e.getMessage());
							} catch (ConcurrentAccessException e) {
								getLogger().error("saveSocialBehaviours()", e);
								response.setStatus(ResponseStatus.FAILED);
								response.setMsg(e.getMessage());
								serviceResponse.setStatus(ResponseStatus.FAILED);
								serviceResponse.setMsg(e.getMessage());
							}
						//}
					}
				}else {
					socialBehaviourRecordDAO.save(socialBehavEntity);
					response.setStatus(ResponseStatus.SUCCESS);
					serviceResponse.setStatus(ResponseStatus.SUCCESS);
				}
				//add response to list and send back to ui
				saveResponse.add(response);
			}
			
			serviceResponse.setResult(saveResponse);
			return serviceResponse;
		}

	@Transactional
	public IValueObject getSocialBehaviourRecordsByEntityIdTermGrade(StudentRecordVO studentRecordVO) {
		SearchCriteriaVO searchValue= studentRecordVO.getSearchCriteria();
		List<SocialBehaviorRecordVO> resultVoList = new ArrayList<SocialBehaviorRecordVO>();
		ServiceResponse<SocialBehaviorRecordVO> response = new ServiceResponse<SocialBehaviorRecordVO>();
		Long entityId=searchValue.getStudentEntityId();
		int gradeId=searchValue.getGradeId();
		int termId=searchValue.getTermId();
		getLogger().info("getSocialBehaviourRecordsByEntityIdTermGrade : entityId:"+entityId +", gradeId :"+gradeId+", termId: "+termId);
		List<SocialBehaviorRecordEntity> searchedRecords=socialBehaviourRecordDAO.fetchDetailsByEntityIdTermGrade(entityId,gradeId,termId);
		if(CollectionUtils.isEmpty(searchedRecords)){
			response.setStatus(ResponseStatus.NOT_FOUND);
			getLogger().info("getSocialBehaviourRecordsByEntityIdTermGrade : No record found in db for given params");
		}else{
			getLogger().info("getSocialBehaviourRecordsByEntityIdTermGrade : Total records found :"+ searchedRecords);
			for(SocialBehaviorRecordEntity entity: searchedRecords){
				SocialBehaviorRecordVO vo = helper.getVO(entity);
				resultVoList.add(vo);
			}			
			response.setStatus(ResponseStatus.SUCCESS);
		}
		response.setResult(resultVoList);
		return response;		
	}

	@Transactional
	public List<SocialBehaviorRecordVO> getSocialBehavioursByGrades(Long studentEntity,
			List<Integer> gradeValueList) {
		// TODO Auto-generated method stub
		List<SocialBehaviorRecordVO> voList = new ArrayList<SocialBehaviorRecordVO>();
		List<SocialBehaviorRecordEntity> socioBehavList = new ArrayList<SocialBehaviorRecordEntity>();

		SocialBehaviorRecordHelper helper = new SocialBehaviorRecordHelper();

		socioBehavList = socialBehaviourRecordDAO.fetchSocialBehavioursByGrades(studentEntity, gradeValueList);
		for (SocialBehaviorRecordEntity entity : socioBehavList) {
			voList.add(helper.getVO(entity));
		}
		return voList;

	}

	@Override
	@Transactional
	public List<GenericAggregator> getStrengthWeaknessByNamedQuery(Long studentEntityId, List<Integer> gradeValueList) {

		return socialBehaviourRecordDAO.getStrengthForSocialBehaviour(studentEntityId, gradeValueList);
	}

	/*@Transactional
	public List<SocialBehaviorRecordVO> getSocialBehaviourByEntityIdGrade(Long entityId, int gradeId) {
		// TODO Auto-generated method stub

		List<SocialBehaviorRecordVO> voList = new ArrayList<SocialBehaviorRecordVO>();
		List<SocialBehaviorRecordEntity> socioList = new ArrayList<SocialBehaviorRecordEntity>();

		SocialBehaviorRecordHelper helper = new SocialBehaviorRecordHelper();
		socioList = socialBehaviourRecordDAO.fetchSocialBehavioursByGrades(entityId,
				new ArrayList<Integer>(Arrays.asList(gradeId)));

		for (SocialBehaviorRecordEntity entity : socioList) {
			voList.add(helper.getVO(entity));
		}
		return voList;
	}
*/
	
	

}
